using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using NUnit.Framework;
using SCSFContrib.CompositeUI.WPF.UIElements;

namespace SCSFContrib.CompositeUI.WPF.UnitTest.UIElements
{
	[TestFixture]
	public sealed class ItemsControlUIAdapterTest : UnitTest
	{
		private ItemsControlUIAdapter _itemsControlUIAdapter;
		private ItemsControl _itemsControl;

		protected override void SetUpCore()
		{
			base.SetUpCore();
			_itemsControl = new ItemsControl();
			_itemsControlUIAdapter = new ItemsControlUIAdapter(_itemsControl);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Constructor_ShouldThrowIfItemsControlIsNull()
		{
			new ItemsControlUIAdapter(null);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void GetIndex_ShouldThrowIfItemIsNull()
		{
			ItemsControlUIAdapter.GetIndex(null);
		}

		[Test]
		public void GetIndex_ShouldReturnNullByDefault()
		{
			Assert.IsNull(ItemsControlUIAdapter.GetIndex(new TextBox()));
			Assert.IsNull(ItemsControlUIAdapter.GetIndex(new Button()));
			Assert.IsNull(ItemsControlUIAdapter.GetIndex(new FrameworkElement()));
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void SetIndex_ShouldThrowIfItemIsNull()
		{
			ItemsControlUIAdapter.SetIndex(null, 1);
		}

		[Test]
		public void SetIndex_ShouldAssignGivenValue()
		{
			Button button = new Button();
			TextBox textBox = new TextBox();
			MenuItem menuItem1 = new MenuItem();
			MenuItem menuItem2 = new MenuItem();

			ItemsControlUIAdapter.SetIndex(button, 1);
			ItemsControlUIAdapter.SetIndex(textBox, -2);
			ItemsControlUIAdapter.SetIndex(menuItem1, 3000);
			ItemsControlUIAdapter.SetIndex(menuItem2, 30);
			ItemsControlUIAdapter.SetIndex(menuItem2, null);

			Assert.AreEqual(1, ItemsControlUIAdapter.GetIndex(button));
			Assert.AreEqual(-2, ItemsControlUIAdapter.GetIndex(textBox));
			Assert.AreEqual(3000, ItemsControlUIAdapter.GetIndex(menuItem1));
			Assert.IsNull(ItemsControlUIAdapter.GetIndex(menuItem2));
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Add_ShouldThrowIfItemIsNull()
		{
			_itemsControlUIAdapter.Add(null);
		}

		[Test]
		public void Add_ShouldAddItemToItemsControl()
		{
			TextBox textBox = new TextBox();
			Assert.AreEqual(0, _itemsControl.Items.Count);
			_itemsControlUIAdapter.Add(textBox);
			Assert.AreEqual(1, _itemsControl.Items.Count);
			Assert.IsTrue(_itemsControl.Items.Contains(textBox));

			Button button = new Button();
			_itemsControlUIAdapter.Add(button);
			Assert.AreEqual(2, _itemsControl.Items.Count);
			Assert.IsTrue(_itemsControl.Items.Contains(textBox));
			Assert.IsTrue(_itemsControl.Items.Contains(button));
			Assert.AreEqual(0, _itemsControl.Items.IndexOf(textBox));
			Assert.AreEqual(1, _itemsControl.Items.IndexOf(button));
		}

		[Test]
		public void Add_ShouldUseIndexesToArrangeItems()
		{
			MenuItem menuItem1 = new MenuItem();
			MenuItem menuItem2 = new MenuItem();
			MenuItem menuItem3 = new MenuItem();
			MenuItem menuItem4 = new MenuItem();
			MenuItem menuItem5 = new MenuItem();
			MenuItem menuItem6 = new MenuItem();

			ItemsControlUIAdapter.SetIndex(menuItem1, -320);
			ItemsControlUIAdapter.SetIndex(menuItem2, 0);
			ItemsControlUIAdapter.SetIndex(menuItem3, 1);
			ItemsControlUIAdapter.SetIndex(menuItem4, 2398);
			ItemsControlUIAdapter.SetIndex(menuItem5, int.MaxValue);

			_itemsControlUIAdapter.Add(menuItem3);
			_itemsControlUIAdapter.Add(menuItem1);
			_itemsControlUIAdapter.Add(menuItem5);
			_itemsControlUIAdapter.Add(menuItem4);
			_itemsControlUIAdapter.Add(menuItem2);
			_itemsControlUIAdapter.Add(menuItem6);

			Assert.AreSame(menuItem1, _itemsControl.Items[0]);
			Assert.AreSame(menuItem2, _itemsControl.Items[1]);
			Assert.AreSame(menuItem3, _itemsControl.Items[2]);
			Assert.AreSame(menuItem4, _itemsControl.Items[3]);
			Assert.AreSame(menuItem5, _itemsControl.Items[4]);
			Assert.AreSame(menuItem6, _itemsControl.Items[5]);
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void Remove_ShouldThrowIfItemIsNull()
		{
			_itemsControlUIAdapter.Remove(null);
		}

		[Test]
		public void Remove_ShouldDoNothingIfItemIsntInItemsControl()
		{
			_itemsControlUIAdapter.Remove(new Button());
			_itemsControlUIAdapter.Remove(new TextBlock());
		}

		[Test]
		public void Remove_ShouldRemoveItemIfInItemsControl()
		{
			Button button = new Button();
			TextBox textBox = new TextBox();

			_itemsControl.Items.Add(button);
			_itemsControl.Items.Add(textBox);

			Assert.IsTrue(_itemsControl.Items.Contains(button));
			Assert.IsTrue(_itemsControl.Items.Contains(textBox));
			_itemsControlUIAdapter.Remove(button);
			_itemsControlUIAdapter.Remove(textBox);
			Assert.IsFalse(_itemsControl.Items.Contains(button));
			Assert.IsFalse(_itemsControl.Items.Contains(textBox));
		}
	}
}